#include <string>

#include "HiKernel/HiField.h"
#include "HiKernel/HiContainer.h"

HiField::HiField(HiContainer *parent, short id, std::string strName) : m_pParent(parent)
{
	m_pParent->AddField(this);
	m_sId = id;
	m_strName = strName;
	m_pInput = NULL;
	m_iDirty = 0;
	m_bSuspend = false;
}

HiField::~HiField()
{
	if(m_pInput != NULL)
	{
		delete m_pInput;
	}
	for(unsigned int i =0 ;i<m_vInputs.size(); i++)
	{
		delete m_vInputs[i];
		m_vInputs[i] = NULL;
	}
	for(unsigned int i =0; i<m_vOutputs.size(); i++)
	{
		delete m_vOutputs[i];
		m_vOutputs[i] = NULL;
	}
	m_vInputs.clear();
	m_vOutputs.clear();
}

void HiField::Connect(HiField *dest)
{
	if(dest == NULL)
		return ;

	m_vOutputs.push_back(dest);

	dest->GetInputs()->push_back(this);
}

void HiField::DisConnect(HiField *dest)
{
	if(dest == NULL)
		return ;

	if(m_vOutputs.empty())
		return ;

	for(std::vector<HiField*>::iterator it=m_vOutputs.begin(); it!=m_vOutputs.end(); it++)
	{
		if(*it == dest)
		{
			m_vOutputs.erase(it);
			break;
		}
	}
	if(dest->GetInputs()->empty())
		return ;

	for(std::vector<HiField*>::iterator it=m_vInputs.begin(); it!=m_vInputs.end(); it++)
	{
		if(*it == this)
		{
			m_vInputs.erase(it);
			break;
		}
	}
}

void HiField::Validate()
{
	if (m_pInput && m_pInput->GetDirty() != 0)
	{
		if(m_bSuspend==false)
		{
			Copy(m_pInput);
			m_pInput = NULL;
			m_iDirty = 1;
		}
    }
}

void HiField::SetID(float id)
{
	m_sId = id;
}

void HiField::SetName(std::string strName)
{
	m_strName = strName;
}

void HiField::SetInput(HiField *pField)
{
	m_pInput = pField;
}

short HiField::GetID()
{
	return m_sId;
}

void HiField::SetSuspend(bool bSuspend)
{
	m_bSuspend = bSuspend;
}

void HiField::Suspend()
{
	m_bSuspend = false;
}

void HiField::Resume()
{
	m_bSuspend = true;
}

void HiField::SetDirty(int iDirty)
{
	m_iDirty = iDirty;
}

int HiField::GetDirty()
{
	return m_iDirty;
}

bool HiField::GetSuspend()
{
	return m_bSuspend;
}

const std::string HiField::GetName()
{
	return m_strName;
}

HiField* HiField::GetInput()
{
	return m_pInput;
}

std::vector<HiField*>* HiField::GetInputs()
{
	return &m_vInputs;
}

std::vector<HiField*> HiField::GetOutputs()
{
	return m_vOutputs;
}

//std::string HiSFVec3f::m_strTypeName = "HiSFVec3f";

HiSFVec3f::HiSFVec3f(HiContainer *parent, short id, std::string strName) : HiField(parent, id, strName)
{
//	parent->AddField(this);


	m_vStorage = new D3DXVECTOR3;
	m_vStorage->x = 0.0f;
	m_vStorage->y = 0.0f;
	m_vStorage->z = 0.0f;
	m_vScale.x = 1.0f;
	m_vScale.y = 1.0f;
	m_vScale.z = 1.0f;
	m_vOffset.x = 0.0f;
	m_vOffset.y = 0.0f;
	m_vOffset.z = 0.0f;
	m_vOrder.x = 1.0f;
	m_vOrder.y = 1.0f;
	m_vOrder.z = 1.0f;
}

HiSFVec3f::HiSFVec3f(HiContainer *parent, short id, std::string strName, D3DXVECTOR3 *val) : HiField(parent, id, strName)
{
//	parent->AddField(this);

	m_vStorage = val;
	m_vScale.x = 1.0f;
	m_vScale.y = 1.0f;
	m_vScale.z = 1.0f;
	m_vOffset.x = 0.0f;
	m_vOffset.y = 0.0f;
	m_vOffset.z = 0.0f;
	m_vOrder.x = 1.0f;
	m_vOrder.y = 1.0f;
	m_vOrder.z = 1.0f;
}

HiSFVec3f::~HiSFVec3f()
{
	m_vStorage = NULL;
}

void HiSFVec3f::Copy(HiField *pField)
{
	D3DXVECTOR3 temp = *(((HiSFVec3f *)pField)->m_vStorage);
	m_vStorage->x = temp.x* m_vScale.x   + m_vOffset.x;
	m_vStorage->y = temp.y* m_vScale.y + m_vOffset.y;
	m_vStorage->z = temp.z* m_vScale.z + m_vOffset.z;
}

void HiSFVec3f::Set(const D3DXVECTOR3 &vVec)
{
	*m_vStorage = vVec;
	SetDirty(1);
}

//std::string HiVec3f::m_strTypeName = "HiVec3f";

HiVec3f::HiVec3f(HiContainer *parent, short id, std::string strName) : HiField(parent, id, strName)
{
//	parent->AddField(this);

	m_pStorage = new float[3];
}

HiVec3f::HiVec3f(HiContainer *parent, short id, std::string strName, float *val) : HiField(parent, id, strName)
{
	m_pStorage = val;
}

HiVec3f::~HiVec3f()
{
}

void HiVec3f::Copy(HiField *pField)
{
	m_pStorage = NULL;
}

